<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>XML格式化工具</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        :root {
            --bg-color: #e0f7fa;
            --panel-bg: #ffffff;
            --primary: #00838f;
            --primary-light: #4fb3bf;
            --primary-dark: #005662;
            --accent: #ff8a65;
            --text: #263238;
            --text-light: #546e7a;
            --success: #4caf50;
            --error: #f44336;
            --border: #b2ebf2;
            --tree-indent: 20px;
            --shadow: 0 4px 20px rgba(0, 131, 143, 0.15);
        }

        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: var(--bg-color);
            color: var(--text);
            line-height: 1.6;
            padding: 20px;
            min-height: 100vh;
            background-image:
                radial-gradient(circle at 10% 20%, rgba(79, 179, 191, 0.1) 0%, transparent 25%),
                radial-gradient(circle at 90% 80%, rgba(255, 138, 101, 0.1) 0%, transparent 25%);
        }

        .container {
            max-width: 1200px;
            margin: 0 auto;
        }

        header {
            text-align: center;
            margin-bottom: 30px;
            padding: 20px;
        }

        h1 {
            font-size: 2.8rem;
            margin-bottom: 10px;
            color: var(--primary-dark);
            text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
        }

        h1 i {
            color: var(--primary);
            margin-right: 15px;
        }

        .subtitle {
            color: var(--text-light);
            font-size: 1.1rem;
            max-width: 600px;
            margin: 0 auto;
        }

        .panel {
            background: var(--panel-bg);
            border-radius: 12px;
            box-shadow: var(--shadow);
            border: 1px solid var(--border);
            position: relative;
            overflow: hidden;
            margin-bottom: 25px;
            transition: all 0.3s ease;
        }

        .panel-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 15px 25px;
            background: linear-gradient(to right, var(--primary), var(--primary-light));
            color: white;
            cursor: pointer;
        }

        .panel-header h2 {
            display: flex;
            align-items: center;
            gap: 12px;
            font-size: 1.4rem;
        }

        .panel-actions {
            display: flex;
            gap: 10px;
        }

        .btn-icon {
            background: rgba(255, 255, 255, 0.2);
            border: none;
            border-radius: 50%;
            width: 36px;
            height: 36px;
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: pointer;
            color: white;
            font-size: 1.1rem;
            transition: all 0.3s;
        }

        .btn-icon:hover {
            background: rgba(255, 255, 255, 0.3);
            transform: scale(1.1);
        }

        .panel-content {
            padding: 25px;
            transition: all 0.3s ease;
        }

        textarea {
            width: 100%;
            min-height: 200px;
            padding: 20px;
            background: #fafafa;
            color: var(--text);
            border: 1px solid var(--border);
            border-radius: 10px;
            font-family: 'Consolas', monospace;
            font-size: 15px;
            resize: vertical;
            transition: border-color 0.3s, box-shadow 0.3s;
            line-height: 1.5;
        }

        textarea:focus {
            border-color: var(--primary);
            outline: none;
            box-shadow: 0 0 0 3px rgba(0, 131, 143, 0.2);
        }

        .controls {
            display: flex;
            flex-wrap: wrap;
            gap: 15px;
            margin-top: 20px;
        }

        .btn {
            padding: 14px 25px;
            border-radius: 50px;
            border: none;
            cursor: pointer;
            font-weight: 600;
            transition: all 0.2s ease;
            display: flex;
            align-items: center;
            gap: 10px;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
            font-size: 1rem;
        }

        .btn-primary {
            background: var(--primary);
            color: white;
        }

        .btn-primary:hover {
            background: var(--primary-dark);
            transform: translateY(-2px);
            box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15);
        }

        .btn-secondary {
            background: white;
            color: var(--primary);
            border: 2px solid var(--primary);
        }

        .btn-secondary:hover {
            background: #e0f7fa;
        }

        .btn-accent {
            background: var(--accent);
            color: white;
        }

        .btn-accent:hover {
            background: #ff7043;
            transform: translateY(-2px);
            box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15);
        }

        .xml-tree {
            background: #fafafa;
            border-radius: 10px;
            padding: 25px;
            font-family: 'Consolas', monospace;
            font-size: 15px;
            min-height: 200px;
            border: 1px solid var(--border);
            box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05);
            max-height: 50vh;
            overflow-y: auto;
        }

        .tree-node {
            margin-bottom: 8px;
            word-break: break-word;
            white-space: pre-wrap;
            position: relative;
            padding-left: 12px;
        }

        .tree-node::before {
            content: '';
            position: absolute;
            left: 0;
            top: 0;
            bottom: 0;
            width: 2px;
            background: var(--primary);
            opacity: 0.2;
        }

        .tree-tag {
            color: var(--primary-dark);
            font-weight: bold;
        }

        .tree-attr-name {
            color: var(--primary);
        }

        .tree-attr-value {
            color: #e64a19;
        }

        .tree-text {
            color: #546e7a;
        }

        .tree-comment {
            color: #78909c;
            font-style: italic;
        }

        .toggle-btn {
            background: none;
            border: none;
            color: var(--primary);
            cursor: pointer;
            width: 24px;
            height: 24px;
            text-align: center;
            margin-right: 8px;
            transition: transform 0.2s;
            border-radius: 4px;
            display: inline-flex;
            align-items: center;
            justify-content: center;
        }

        .toggle-btn:hover {
            background: rgba(0, 131, 143, 0.1);
        }

        .children {
            padding-left: var(--tree-indent);
            margin-left: 15px;
            margin-top: 8px;
            border-left: 1px dashed var(--border);
        }

        .collapsed .children {
            display: none;
        }

        .leaf-node {
            display: inline;
        }

        .notification {
            position: fixed;
            top: 25px;
            right: 25px;
            padding: 16px 25px;
            border-radius: 10px;
            color: white;
            font-weight: 600;
            opacity: 0;
            transform: translateX(100%);
            transition: all 0.3s ease;
            z-index: 1000;
            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.15);
            font-size: 1.1rem;
        }

        .notification.show {
            opacity: 1;
            transform: translateX(0);
        }

        .notification.success {
            background: var(--success);
        }

        .notification.error {
            background: var(--error);
        }

        .stats {
            display: flex;
            gap: 20px;
            margin-top: 20px;
            flex-wrap: wrap;
        }

        .stat-card {
            background: rgba(0, 131, 143, 0.05);
            padding: 15px 20px;
            border-radius: 10px;
            min-width: 140px;
            border: 1px solid var(--border);
            flex: 1;
        }

        .stat-label {
            color: var(--text-light);
            font-size: 0.9rem;
        }

        .stat-value {
            font-weight: bold;
            color: var(--primary);
            font-size: 1.4rem;
            margin-top: 5px;
        }

        footer {
            text-align: center;
            margin-top: 50px;
            padding-top: 25px;
            color: var(--text-light);
            font-size: 1rem;
            border-top: 1px solid var(--border);
        }

        .attr-container {
            display: inline-block;
            word-break: break-word;
            vertical-align: top;
        }

        .tag-container {
            display: inline-block;
        }

        .tag-end {
            display: inline;
            margin-left: 5px;
        }

        .fullscreen {
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            z-index: 1000;
            background: white;
            padding: 20px;
            overflow: auto;
        }

        .fullscreen textarea {
            height: calc(100vh - 150px) !important;
            min-height: auto;
        }

        .fullscreen .xml-tree {
            height: calc(100vh - 200px);
            max-height: none;
        }

        .panel.collapsed .panel-content {
            display: none;
        }

        @media (max-width: 900px) {
            .controls {
                flex-direction: column;
            }

            .btn {
                width: 100%;
                justify-content: center;
            }

            h1 {
                font-size: 2.2rem;
            }

            .xml-tree {
                padding: 15px;
                font-size: 14px;
            }

            .stats {
                flex-direction: column;
                gap: 12px;
            }

            .stat-card {
                min-width: 100%;
            }
        }

        @media (max-width: 600px) {
            body {
                padding: 15px;
            }

            h1 {
                font-size: 1.8rem;
            }

            .subtitle {
                font-size: 1rem;
            }

            .panel-content {
                padding: 15px;
            }

            .panel-header h2 {
                font-size: 1.2rem;
            }

            .btn {
                padding: 12px 15px;
                font-size: 0.95rem;
            }
        }
    </style>
</head>
<body>
<div class="container">
    <header>
        <h1><i class="fas fa-code"></i> XML格式化工具</h1>
        <p class="subtitle">输入XML内容，获取格式化的树形结构展示。支持节点折叠、自动换行、XML压缩等功能</p>
    </header>

    <section class="panel" id="inputPanel">
        <div class="panel-header" id="toggleInput">
            <h2><i class="fas fa-edit"></i> XML输入区域</h2>
            <div class="panel-actions">
                <button class="btn-icon" id="fullscreenInputBtn" title="全屏">
                    <i class="fas fa-expand"></i>
                </button>
                <button class="btn-icon" id="collapseBtn" title="折叠">
                    <i class="fas fa-chevron-down"></i>
                </button>
            </div>
        </div>
        <div class="panel-content">
                <textarea id="xmlInput" placeholder="在此输入XML内容...">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;library&gt;
  &lt;book id="bk101"
        category="Technology"
        language="English"
        published="true"
        format="Hardcover"
        isbn="978-3-16-148410-0"
        pages="432"
        weight="1.2kg"&gt;
    &lt;title&gt;XML Developer's Guide&lt;/title&gt;
    &lt;author firstName="Matthew" lastName="Gambardella"&gt;Gambardella, Matthew&lt;/author&gt;
    &lt;description&gt;An in-depth look at creating applications with XML. This comprehensive guide covers everything from the basics to advanced topics including XSLT, XPath, and XML Schema. Perfect for both beginners and experienced developers.&lt;/description&gt;
    &lt;price currency="USD" discount="10%" tax="5%"&gt;44.95&lt;/price&gt;
    &lt;publish_date&gt;2000-10-01&lt;/publish_date&gt;
  &lt;/book&gt;
  &lt;book id="bk102"
        category="Fiction"
        language="English"
        published="true"
        format="Paperback"
        isbn="978-0-06-112008-4"
        pages="320"
        weight="0.8kg"&gt;
    &lt;title&gt;Midnight Rain&lt;/title&gt;
    &lt;author firstName="Kim" lastName="Ralls"&gt;Ralls, Kim&lt;/author&gt;
    &lt;description&gt;A former architect battles corporate zombies, an evil sorceress, and her own childhood to become queen of the world. This fantasy novel explores themes of power, identity, and redemption in a unique and captivating way.&lt;/description&gt;
    &lt;price currency="EUR" discount="15%" tax="7%"&gt;5.95&lt;/price&gt;
    &lt;publish_date&gt;2000-12-16&lt;/publish_date&gt;
  &lt;/book&gt;
  &lt;info&gt;
    &lt;library_name&gt;City Central Library&lt;/library_name&gt;
    &lt;address&gt;123 Knowledge Street, Education City, CA 90210, United States&lt;/address&gt;
    &lt;contact email="contact@citylibrary.example.com" phone="+1-555-1234"&gt;contact@citylibrary.example.com&lt;/contact&gt;
    &lt;opening_hours&gt;Monday to Friday: 9:00 AM - 9:00 PM, Saturday and Sunday: 10:00 AM - 6:00 PM&lt;/opening_hours&gt;
  &lt;/info&gt;
&lt;/library&gt;</textarea>
            <div class="controls">
                <button class="btn btn-primary" id="formatBtn">
                    <i class="fas fa-magic"></i> 格式化XML
                </button>
                <button class="btn btn-accent" id="compressBtn">
                    <i class="fas fa-compress-arrows-alt"></i> 压缩XML
                </button>
                <button class="btn btn-secondary" id="restoreBtn">
                    <i class="fas fa-history"></i> 恢复原始XML
                </button>
                <button class="btn btn-secondary" id="copyInputBtn">
                    <i class="fas fa-copy"></i> 复制输入
                </button>
                <button class="btn btn-secondary" id="exampleBtn">
                    <i class="fas fa-lightbulb"></i> 加载示例
                </button>
                <button class="btn btn-secondary" id="clearBtn">
                    <i class="fas fa-trash-alt"></i> 清空内容
                </button>
            </div>
        </div>
    </section>

    <section class="panel">
        <div class="panel-header">
            <h2><i class="fas fa-tree"></i> 格式化结果</h2>
            <div class="panel-actions">
                <button class="btn-icon" id="copyOutputBtn" title="复制结果">
                    <i class="fas fa-copy"></i>
                </button>
                <button class="btn-icon" id="fullscreenOutputBtn" title="全屏">
                    <i class="fas fa-expand"></i>
                </button>
                <button class="btn-icon" id="collapseAllBtn" title="折叠全部">
                    <i class="fas fa-compress"></i>
                </button>
                <button class="btn-icon" id="expandAllBtn" title="展开全部">
                    <i class="fas fa-expand"></i>
                </button>
            </div>
        </div>
        <div class="panel-content">
            <div class="xml-tree" id="xmlTree">
                <p class="tree-text">格式化结果将显示在这里...</p>
            </div>
            <div class="stats">
                <div class="stat-card">
                    <div class="stat-label">元素总数</div>
                    <div class="stat-value" id="elementCount">0</div>
                </div>
                <div class="stat-card">
                    <div class="stat-label">属性总数</div>
                    <div class="stat-value" id="attributeCount">0</div>
                </div>
                <div class="stat-card">
                    <div class="stat-label">最深层级</div>
                    <div class="stat-value" id="maxDepth">0</div>
                </div>
                <div class="stat-card">
                    <div class="stat-label">解析状态</div>
                    <div class="stat-value" id="parseStatus">等待中</div>
                </div>
            </div>
        </div>
    </section>

    <footer>
        <p>XML格式化工具 &copy; 2023 | 支持XML 1.0标准 | 天青色主题设计</p>
    </footer>
</div>

<div class="notification" id="notification"></div>

<script>
    document.addEventListener('DOMContentLoaded', function() {
        // DOM元素
        const xmlInput = document.getElementById('xmlInput');
        const xmlTree = document.getElementById('xmlTree');
        const inputPanel = document.getElementById('inputPanel');
        const collapseBtn = document.getElementById('collapseBtn');
        const toggleInput = document.getElementById('toggleInput');

        // 按钮
        const formatBtn = document.getElementById('formatBtn');
        const compressBtn = document.getElementById('compressBtn');
        const restoreBtn = document.getElementById('restoreBtn');
        const copyInputBtn = document.getElementById('copyInputBtn');
        const copyOutputBtn = document.getElementById('copyOutputBtn');
        const fullscreenInputBtn = document.getElementById('fullscreenInputBtn');
        const fullscreenOutputBtn = document.getElementById('fullscreenOutputBtn');
        const clearBtn = document.getElementById('clearBtn');
        const exampleBtn = document.getElementById('exampleBtn');
        const expandAllBtn = document.getElementById('expandAllBtn');
        const collapseAllBtn = document.getElementById('collapseAllBtn');

        // 统计元素
        const elementCount = document.getElementById('elementCount');
        const attributeCount = document.getElementById('attributeCount');
        const maxDepth = document.getElementById('maxDepth');
        const parseStatus = document.getElementById('parseStatus');

        // 通知
        const notification = document.getElementById('notification');

        // 状态变量
        let isInputCollapsed = false;
        let originalXml = "";
        let elementCounter = 0;
        let attributeCounter = 0;
        let depthCounter = 0;

        // 示例XML
        const exampleXML = `<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<book id="bk101" category="Technology" language="English" published="true"
    format="Hardcover" isbn="978-3-16-148410-0" pages="432" weight="1.2kg">
<title>XML Developer's Guide</title>
<author firstName="Matthew" lastName="Gambardella">Gambardella, Matthew</author>
<description>An in-depth look at creating applications with XML. This comprehensive guide covers everything from the basics to advanced topics.</description>
<price currency="USD" discount="10%" tax="5%">44.95</price>
<publish_date>2000-10-01</publish_date>
</book>
<book id="bk102" category="Fiction" language="English" published="true"
    format="Paperback" isbn="978-0-06-112008-4" pages="320" weight="0.8kg">
<title>Midnight Rain</title>
<author firstName="Kim" lastName="Ralls">Ralls, Kim</author>
<description>A former architect battles corporate zombies, an evil sorceress, and her own childhood to become queen of the world.</description>
<price currency="EUR" discount="15%" tax="7%">5.95</price>
<publish_date>2000-12-16</publish_date>
</book>
<info>
<library_name>City Central Library</library_name>
<address>123 Knowledge Street, Education City, CA 90210, United States</address>
<contact>contact@citylibrary.example.com</contact>
<opening_hours>Mon-Fri: 9AM-9PM, Sat-Sun: 10AM-6PM</opening_hours>
</info>
</catalog>`;

        // 切换输入区域折叠状态
        toggleInput.addEventListener('click', toggleCollapse);

        // 格式化XML
        formatBtn.addEventListener('click', formatXML);

        // 压缩XML
        compressBtn.addEventListener('click', function() {
            const xmlString = xmlInput.value.trim();
            if (!xmlString) {
                showNotification('请输入XML内容', 'error');
                return;
            }

            try {
                // 保存原始XML
                originalXml = xmlInput.value;

                // 压缩XML
                const parser = new DOMParser();
                const xmlDoc = parser.parseFromString(xmlString, 'text/xml');

                // 检查解析错误
                const parserError = xmlDoc.getElementsByTagName('parsererror');
                if (parserError.length) {
                    throw new Error('XML解析错误: ' + parserError[0].textContent);
                }

                // 序列化并压缩
                const serializer = new XMLSerializer();
                let compressedXML = serializer.serializeToString(xmlDoc);
                compressedXML = compressedXML
                    .replace(/>\s+</g, '><')
                    .replace(/\s+/g, ' ')
                    .trim();

                xmlInput.value = compressedXML;
                showNotification('XML压缩成功', 'success');

                // 更新按钮状态
                restoreBtn.disabled = false;
            } catch (error) {
                showNotification(error.message, 'error');
            }
        });

        // 恢复原始XML
        restoreBtn.addEventListener('click', function() {
            if (originalXml) {
                xmlInput.value = originalXml;
                showNotification('原始XML已恢复', 'success');
                formatXML();
            } else {
                showNotification('没有可恢复的原始XML', 'error');
            }
        });

        // 复制输入内容
        copyInputBtn.addEventListener('click', function() {
            if (xmlInput.value.trim()) {
                xmlInput.select();
                document.execCommand('copy');
                showNotification('XML输入已复制到剪贴板', 'success');
            } else {
                showNotification('没有内容可复制', 'error');
            }
        });

        // 复制输出内容
        copyOutputBtn.addEventListener('click', function() {
            if (xmlTree.textContent.trim() && xmlTree.textContent !== "格式化结果将显示在这里...") {
                const textArea = document.createElement('textarea');
                textArea.value = xmlTree.textContent;
                document.body.appendChild(textArea);
                textArea.select();
                document.execCommand('copy');
                document.body.removeChild(textArea);
                showNotification('格式化结果已复制到剪贴板', 'success');
            } else {
                showNotification('没有内容可复制', 'error');
            }
        });

        // 全屏输入
        fullscreenInputBtn.addEventListener('click', function() {
            const inputArea = document.querySelector('#inputPanel .panel-content');
            inputArea.classList.toggle('fullscreen');
            if (inputArea.classList.contains('fullscreen')) {
                fullscreenInputBtn.innerHTML = '<i class="fas fa-compress"></i>';
                fullscreenInputBtn.title = "退出全屏";
            } else {
                fullscreenInputBtn.innerHTML = '<i class="fas fa-expand"></i>';
                fullscreenInputBtn.title = "全屏";
            }
        });

        // 全屏输出
        fullscreenOutputBtn.addEventListener('click', function() {
            const outputContent = document.querySelector('.panel:last-child .panel-content');
            outputContent.classList.toggle('fullscreen');
            if (outputContent.classList.contains('fullscreen')) {
                fullscreenOutputBtn.innerHTML = '<i class="fas fa-compress"></i>';
                fullscreenOutputBtn.title = "退出全屏";
            } else {
                fullscreenOutputBtn.innerHTML = '<i class="fas fa-expand"></i>';
                fullscreenOutputBtn.title = "全屏";
            }
        });

        // 清空内容
        clearBtn.addEventListener('click', function() {
            xmlInput.value = '';
            xmlTree.innerHTML = '<p class="tree-text">格式化结果将显示在这里...</p>';
            showNotification('内容已清空', 'success');
            resetStats();
            originalXml = "";
            restoreBtn.disabled = true;
        });

        // 加载示例
        exampleBtn.addEventListener('click', function() {
            xmlInput.value = exampleXML;
            showNotification('示例已加载', 'success');
            formatXML();
        });

        // 展开全部节点
        expandAllBtn.addEventListener('click', function() {
            const collapsedNodes = xmlTree.querySelectorAll('.collapsed');
            collapsedNodes.forEach(node => {
                node.classList.remove('collapsed');
                const icon = node.querySelector('.toggle-btn i');
                if (icon) {
                    icon.classList.remove('fa-caret-right');
                    icon.classList.add('fa-caret-down');
                }
            });
            showNotification('所有节点已展开', 'success');
        });

        // 折叠全部节点
        collapseAllBtn.addEventListener('click', function() {
            const expandableNodes = xmlTree.querySelectorAll('.tree-node:has(.children)');
            expandableNodes.forEach(node => {
                if (!node.classList.contains('collapsed')) {
                    node.classList.add('collapsed');
                    const icon = node.querySelector('.toggle-btn i');
                    if (icon) {
                        icon.classList.remove('fa-caret-down');
                        icon.classList.add('fa-caret-right');
                    }
                }
            });
            showNotification('所有节点已折叠', 'success');
        });

        // 格式化XML函数
        function formatXML() {
            const xmlString = xmlInput.value.trim();
            if (!xmlString) {
                showNotification('请输入XML内容', 'error');
                return;
            }

            try {
                // 重置统计
                resetStats();

                // 解析XML
                const parser = new DOMParser();
                const xmlDoc = parser.parseFromString(xmlString, 'text/xml');

                // 检查错误
                const parserError = xmlDoc.getElementsByTagName('parsererror');
                if (parserError.length) {
                    throw new Error('XML解析错误: ' + parserError[0].textContent);
                }

                // 清空结果区域
                xmlTree.innerHTML = '';

                // 构建XML树
                buildXMLTree(xmlDoc.documentElement, xmlTree, 1);

                // 更新状态
                parseStatus.textContent = '成功';
                parseStatus.style.color = 'var(--success)';

                showNotification('XML格式化成功', 'success');
            } catch (error) {
                showNotification(error.message, 'error');
                xmlTree.innerHTML = `<p class="tree-text" style="color:var(--error)">${error.message}</p>`;
                parseStatus.textContent = '失败';
                parseStatus.style.color = 'var(--error)';
            }
        }

        // 构建XML树
        function buildXMLTree(node, parentElement, level) {
            // 更新深度
            if (level > depthCounter) {
                depthCounter = level;
                maxDepth.textContent = depthCounter;
            }

            const nodeElement = document.createElement('div');
            nodeElement.classList.add('tree-node');

            // 元素节点
            if (node.nodeType === Node.ELEMENT_NODE) {
                elementCounter++;
                elementCount.textContent = elementCounter;

                const tagContainer = document.createElement('div');
                tagContainer.classList.add('tag-container');

                // 检查是否有子元素
                const hasChildElements = Array.from(node.childNodes).some(
                    child => child.nodeType === Node.ELEMENT_NODE
                );

                // 添加折叠按钮
                if (hasChildElements) {
                    const toggleBtn = document.createElement('button');
                    toggleBtn.classList.add('toggle-btn');
                    toggleBtn.innerHTML = '<i class="fas fa-caret-down"></i>';
                    toggleBtn.addEventListener('click', function() {
                        nodeElement.classList.toggle('collapsed');
                        const icon = this.querySelector('i');
                        icon.classList.toggle('fa-caret-right');
                        icon.classList.toggle('fa-caret-down');
                    });
                    tagContainer.appendChild(toggleBtn);
                }

                // 开始标签
                const startTag = document.createElement('span');

                // 标签名
                const tagName = document.createElement('span');
                tagName.classList.add('tree-tag');
                tagName.textContent = `<${node.tagName}`;
                startTag.appendChild(tagName);

                // 属性
                if (node.attributes.length > 0) {
                    const attrContainer = document.createElement('span');
                    attrContainer.classList.add('attr-container');

                    for (let i = 0; i < node.attributes.length; i++) {
                        const attr = node.attributes[i];
                        attributeCounter++;
                        attributeCount.textContent = attributeCounter;

                        const attrName = document.createElement('span');
                        attrName.classList.add('tree-attr-name');
                        attrName.textContent = ` ${attr.name}=`;

                        const attrValue = document.createElement('span');
                        attrValue.classList.add('tree-attr-value');
                        attrValue.textContent = `"${attr.value}"`;

                        attrContainer.appendChild(attrName);
                        attrContainer.appendChild(attrValue);
                    }

                    startTag.appendChild(attrContainer);
                }

                // 关闭开始标签
                const closingBracket = document.createElement('span');
                closingBracket.classList.add('tree-tag');
                closingBracket.textContent = '>';
                startTag.appendChild(closingBracket);

                tagContainer.appendChild(startTag);
                nodeElement.appendChild(tagContainer);

                // 处理子节点
                if (node.childNodes.length > 0) {
                    const childrenContainer = document.createElement('div');
                    childrenContainer.classList.add('children');

                    let hasElements = false;
                    let textContent = '';

                    for (let i = 0; i < node.childNodes.length; i++) {
                        const child = node.childNodes[i];

                        if (child.nodeType === Node.ELEMENT_NODE) {
                            hasElements = true;
                            buildXMLTree(child, childrenContainer, level + 1);
                        } else if (child.nodeType === Node.TEXT_NODE && child.textContent.trim()) {
                            textContent = child.textContent.trim();
                        } else if (child.nodeType === Node.COMMENT_NODE) {
                            const commentNode = document.createElement('div');
                            commentNode.classList.add('tree-comment');
                            commentNode.textContent = `<!--${child.textContent}-->`;
                            childrenContainer.appendChild(commentNode);
                        }
                    }

                    if (hasElements) {
                        nodeElement.appendChild(childrenContainer);
                    } else if (textContent) {
                        // 文本内容在同一行
                        const textNode = document.createElement('span');
                        textNode.classList.add('tree-text', 'leaf-node');
                        textNode.textContent = textContent;
                        tagContainer.appendChild(textNode);
                    }
                }

                // 结束标签
                const endTag = document.createElement('span');
                endTag.classList.add('tag-end');
                endTag.innerHTML = `<span class="tree-tag">&lt;/${node.tagName}&gt;</span>`;
                tagContainer.appendChild(endTag);
            }

            // 注释节点
            else if (node.nodeType === Node.COMMENT_NODE) {
                const commentNode = document.createElement('div');
                commentNode.classList.add('tree-comment');
                commentNode.textContent = `<!--${node.textContent}-->`;
                nodeElement.appendChild(commentNode);
            }

            // XML声明
            else if (node.nodeType === Node.PROCESSING_INSTRUCTION_NODE) {
                const piNode = document.createElement('div');
                piNode.classList.add('tree-tag');
                piNode.textContent = `<?${node.target} ${node.data}?>`;
                nodeElement.appendChild(piNode);
            }

            parentElement.appendChild(nodeElement);
        }

        // 切换折叠状态
        function toggleCollapse() {
            isInputCollapsed = !isInputCollapsed;
            inputPanel.classList.toggle('collapsed');

            if (isInputCollapsed) {
                collapseBtn.innerHTML = '<i class="fas fa-chevron-up"></i>';
                collapseBtn.title = "展开";
            } else {
                collapseBtn.innerHTML = '<i class="fas fa-chevron-down"></i>';
                collapseBtn.title = "折叠";
            }
        }

        // 显示通知
        function showNotification(message, type) {
            notification.textContent = message;
            notification.className = `notification ${type} show`;

            setTimeout(() => {
                notification.classList.remove('show');
            }, 3000);
        }

        // 重置统计
        function resetStats() {
            elementCounter = 0;
            attributeCounter = 0;
            depthCounter = 0;
            elementCount.textContent = '0';
            attributeCount.textContent = '0';
            maxDepth.textContent = '0';
            parseStatus.textContent = '等待中';
            parseStatus.style.color = 'var(--text)';
        }

        // 初始加载
        setTimeout(() => {
            formatXML();
            // 禁用恢复按钮
            restoreBtn.disabled = true;
        }, 500);
    });
</script>
</body>
</html>
